package bll

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"go-micro.dev/v4/broker"
	"manager/utils"
	"proto/dto"
	log "shadow/collector/logger"
	"shadow/config"
)

// Synchronizer is the struct that wraps the basic init method.
type Synchronizer struct {
	// 订阅消费，同步设备消息
	pubSub broker.Broker
}

func NewSynchronizer(pubSub broker.Broker) *Synchronizer {
	return &Synchronizer{
		pubSub: pubSub,
	}
}

// Init 初始化
func (s *Synchronizer) Init() error {
	fmt.Println("------------------- [Synchronizer init topics:", config.Conf.Topics, "] ------------------ ")
	for i := range config.Conf.Topics {
		topic := config.Conf.Topics[i]
		s.pubSub.Subscribe(topic, s.handle)
	}

	fmt.Println("------------------- [Synchronizer init topics end:", config.Conf.Topics, "] ------------------ ")
	return ProcessEngine.Init()
}

// handle 处理器
func (s *Synchronizer) handle(eventData broker.Event) error {
	defer utils.ExceptionCatch()
	// TODO: 根据topic分析
	method, ok := eventData.Message().Header["method"]
	if !ok {
		log.Errorf("synchronizer handle error: %v", "no topic")
		return nil
	}

	// TODO: 根据操作类型分析
	switch method {
	case "update":
		go func() {
			defer utils.ExceptionCatch()
			obj := dto.DoUpdateRequest{}
			err := proto.Unmarshal(eventData.Message().Body, &obj)
			if err != nil {
				log.Errorf("synchronizer update proto.Unmarshal error: %v", err)
				return
			}

			// TODO: 保存设备影子状态
			if err = ProcessEngine.SaveContext(obj.DeviceName, obj.Type, obj.Items); err != nil {
				log.Errorf("synchronizer update ProcessEngine.SaveContext error: %v", err)
				return
			}
		}()
		return nil
	case "delete":
	}

	return fmt.Errorf("no handler")
}
